###########################################################################
# Happy Hare supporting macros
#   Standalone Tip Forming based on Superslicer
#
# To configure, set
#   'form_tip_macro: _MMU_FORM_TIP' in 'mmu_parameters.cfg'
#
# Default configuration is good for Stealthburner with CW2 and Voron Revo nozzle
#
# This macro is, by default, called by Happy Hare to form filament tip
# prior to unloading. This will need to be tuned for your particular
# setup.  Although the slicer can also perform similarly you must also
# tune tips here. The slicer will be used when printing, this logic will be
# used when not in print.  Because of the need to setup twice, it is recommended
# that you turn off slicer tip forming and to use this routine in all circumstances.
#
# To force Happy Hare to always run this when loading filament add:
#   'force_form_tip_standalone: 1' in 'mmu_parameters.cfg'
#
# Also decide on whether you want toolhead to remain over wipetower while tool
# changing or move to park location (see 'enable_park' in mmu_sequence.cfg)
#
[gcode_macro _MMU_FORM_TIP]
description: Standalone macro that mimics Superslicer process

# Unloading and Ramming values - Initial moves to form and shape tip
variable_unloading_speed_start: 80     # Fast here to separate the filament from meltzone (Very intitial retract SS uses distance of E-15)
variable_unloading_speed: 18           # Too fast forms excessively long tip or hair. Slow is better here UNLOADING_SPEED_START/COOLING_MOVES seems a good start
variable_ramming_volume: 0             # (mm^3) SS default values = 2, 5, 9, 13, 18, 23, 27. Only Used to Simulate SS Ramming during standalone
variable_ss_ramming: 0                 # Set to 0 for standalone ramming (RAMMING_VOLUME), 1 to let the slicer do it (i.e. turn off for standalone)

# Cooling Move Values - To cool the tip formed and separate from strings
variable_cooling_tube_position: 35     # Dragon ST: 35, Dragon HF: 30, Mosquito: 30, Revo: 35, Phaetus Rapido HF: 43; Measured from nozzle to top of heater block
variable_cooling_tube_length: 10       # Dragon ST: 15, Dragon HF: 10, Mosquito: 20, Revo: 10, Phaetus Rapido HF: 22; Top of Heater block to top of heatsink
variable_initial_cooling_speed: 10     # Slow to solidify tip and cool string if formed.
variable_final_cooling_speed: 50       # High speed break the string formed. Too fast = tip deformation during eject. Too Slow = long string/no seperation
variable_toolchange_temp: 0            # Used if you want to lower temp during toolchanges default 0
variable_cooling_moves: 4              # 2-4 is a good start

# SkinnyDip values - To burn off VERY FINE hairs only (This is NOT for long tip reshaping)
variable_use_skinnydip: 1              # Tune this LAST, this is for removal of VERY FINE hairs only (Different than a long tip)
variable_skinnydip_distance: 30        # Start just under Cooling_tube_position and increase - Will depend on how much Ramming Volume is used
variable_dip_insertion_speed: 30       # Medium-Slow - Just long enough to melt the fine hairs. Too slow will pull up molten filament
variable_dip_extraction_speed: 70      # Around 2x Insertion speed, Prevents forming new hairs
variable_melt_zone_pause: 0            # Milliseconds - default 0
variable_cooling_zone_pause: 0         # Milliseconds - default 0 - If you need to adjust here its possible Dip Insertion too slow
variable_use_fast_skinnydip: 0         # Skip the toolhead temp change during skinnydip move - default 0


# Final Eject - for standalone tuning only. Automatically set by `MMU_FORM_TIP` command
variable_final_eject: 0                # Default 0, enable only when tuning process to eject the filament. Don't leave enabled!

# Park filament ready to eject
variable_parking_distance: 0           # Final filament parking position after final cooling move, 0 will leave filament where it naturally ends up

# Extruder speed for non specific movement
variable_extruder_eject_speed: 25      # Used for parking_distance and final_eject

gcode:
    # Initialize Paramaters
    {% set UNLOADING_SPEED_START = params.UNLOADING_SPEED_START|default(printer['gcode_macro _MMU_FORM_TIP']['unloading_speed_start']) %}
    {% set UNLOADING_SPEED = params.UNLOADING_SPEED|default(printer['gcode_macro _MMU_FORM_TIP']['unloading_speed']) %}
    {% set RAMMING_VOLUME = params.RAMMING_VOLUME|default(printer['gcode_macro _MMU_FORM_TIP']['ramming_volume']) %}
    {% set SS_RAMMING = params.SS_RAMMING|default(printer['gcode_macro _MMU_FORM_TIP']['ss_ramming']) %}
    {% set COOLING_TUBE_LENGTH = params.COOLING_TUBE_LENGTH|default(printer['gcode_macro _MMU_FORM_TIP']['cooling_tube_length']) %}
    {% set COOLING_TUBE_POSITION = params.COOLING_TUBE_POSITION|default(printer['gcode_macro _MMU_FORM_TIP']['cooling_tube_position']) %}
    {% set INITIAL_COOLING_SPEED = params.INITIAL_COOLING_SPEED|default(printer['gcode_macro _MMU_FORM_TIP']['initial_cooling_speed']) %}
    {% set FINAL_COOLING_SPEED = params.FINAL_COOLING_SPEED|default(printer['gcode_macro _MMU_FORM_TIP']['final_cooling_speed']) %}
    {% set COOLING_MOVES = params.COOLING_MOVES|default(printer['gcode_macro _MMU_FORM_TIP']['cooling_moves']) %}
    {% set TOOLCHANGE_TEMP = params.TOOLCHANGE_TEMP|default(printer['gcode_macro _MMU_FORM_TIP']['toolchange_temp']) %}
    {% set USE_SKINNYDIP = params.USE_SKINNYDIP|default(printer['gcode_macro _MMU_FORM_TIP']['use_skinnydip']) %}
    {% set USE_FAST_SKINNYDIP = params.USE_FAST_SKINNYDIP|default(printer['gcode_macro _MMU_FORM_TIP']['use_fast_skinnydip']) %}
    {% set SKINNYDIP_DISTANCE = params.SKINNYDIP_DISTANCE|default(printer['gcode_macro _MMU_FORM_TIP']['skinnydip_distance']) %}
    {% set DIP_INSERTION_SPEED = params.DIP_INSERTION_SPEED|default(printer['gcode_macro _MMU_FORM_TIP']['dip_insertion_speed']) %}
    {% set DIP_EXTRACTION_SPEED = params.DIP_EXTRACTION_SPEED|default(printer['gcode_macro _MMU_FORM_TIP']['dip_extraction_speed']) %}
    {% set MELT_ZONE_PAUSE = params.MELT_ZONE_PAUSE|default(printer['gcode_macro _MMU_FORM_TIP']['melt_zone_pause']) %}
    {% set COOLING_ZONE_PAUSE = params.COOLING_ZONE_PAUSE|default(printer['gcode_macro _MMU_FORM_TIP']['cooling_zone_pause']) %}
    {% set EXTRUDER_EJECT_SPEED = params.EXTRUDER_EJECT_SPEED|default(printer['gcode_macro _MMU_FORM_TIP']['extruder_eject_speed']) %}
    {% set PARKING_DISTANCE = params.PARKING_DISTANCE|default(printer['gcode_macro _MMU_FORM_TIP']['parking_distance']) %}
    {% set FINAL_EJECT = params.FINAL_EJECT|default(printer['gcode_macro _MMU_FORM_TIP']['final_eject']) %}

    SAVE_GCODE_STATE NAME=MMU_FORM_TIP_state

    G91 # Relative positioning
    M83 # Relative extrusion
    G92 E0

    SET_PRESSURE_ADVANCE ADVANCE=0 # Temporarily disable pressure advance. Happy Hare will restore it
    {% set OLD_TEMP = printer.extruder.target %}
    {% if SS_RAMMING|int == 0 and RAMMING_VOLUME|int > 0 %} # Standalone Ramming
        {% set RATIO = (RAMMING_VOLUME|float) /23.0 %}
        G1 E{0.5784 * RATIO|float} F299 #7
        G1 E{0.5834 * RATIO|float} F302 #3
        G1 E{0.5918 * RATIO|float} F306 #6
        G1 E{0.6169 * RATIO|float} F319 #6
        G1 E{0.3393 * RATIO|float} F350 #0
        G1 E{0.3363 * RATIO|float} F350 #0
        G1 E{0.7577 * RATIO|float} F392 #6
        G1 E{0.8382 * RATIO|float} F434 #3
        G1 E{0.7776 * RATIO|float} F469 #9
        G1 E{0.1293 * RATIO|float} F469 #9
        G1 E{0.9673 * RATIO|float} F501 #2
        G1 E{1.0176 * RATIO|float} F527 #2
        G1 E{0.5956 * RATIO|float} F544 #6
        G1 E{0.4555 * RATIO|float} F544 #6
        G1 E{1.0662 * RATIO|float} F552 #4
    {% endif %}

    # Set toolchange temperature just prior to filament being extracted from melt zone and wait for set point
    # (SKINNYDIP -- normal mode only)
    # Only used if changing between filament types eg. ABS-->PLA
    {% if TOOLCHANGE_TEMP|float > 0 and USE_FAST_SKINNYDIP|int == 0 %}
         M109 S{TOOLCHANGE_TEMP}
    {% endif %}

    # Unloading - This is where the tip spear shape comes from Faster=longer/pointer/higher stringing
    {% set TOTAL_RETRACTION_DISTANCE = COOLING_TUBE_POSITION|float + COOLING_TUBE_LENGTH|float / 2 - 15 %}
    G1 E-15 F{1.0 * UNLOADING_SPEED_START|float * 60} # Default value from SS - Cannot modify
    G1 E-{0.7 * TOTAL_RETRACTION_DISTANCE} F{1.0 * UNLOADING_SPEED|float * 60}
    G1 E-{0.2 * TOTAL_RETRACTION_DISTANCE} F{0.5 * UNLOADING_SPEED|float * 60}
    G1 E-{0.1 * TOTAL_RETRACTION_DISTANCE} F{0.3 * UNLOADING_SPEED|float * 60}

    {% if TOOLCHANGE_TEMP|float > 0 and USE_FAST_SKINNYDIP|int == 1 %}
        M104 S{TOOLCHANGE_TEMP}
    {% endif %}

    # Generate Cooling Moves - Solidifies tip shape and helps break strings if formed
    {% set SPEED_INC = (FINAL_COOLING_SPEED|float - INITIAL_COOLING_SPEED|float) / (2 * COOLING_MOVES|float - 1) %}
    {% for move in range(COOLING_MOVES|int) %}
        G1 E{COOLING_TUBE_LENGTH} F{(INITIAL_COOLING_SPEED|float + SPEED_INC*move*2) * 60}
        G1 E-{COOLING_TUBE_LENGTH} F{(INITIAL_COOLING_SPEED|float + SPEED_INC*(move*2+1)) * 60}
    {% endfor %}

    # Wait for extruder to reach toolchange temperature after cooling moves complete (SKINNYDIP--fast mode only)
    {% if TOOLCHANGE_TEMP|float > 0 and USE_FAST_SKINNYDIP|int == 1 %}
        M109 S{TOOLCHANGE_TEMP}
    {% endif %}

    # Skinny dip Move - burns off VERY FINE hairs (Good for PLA)
    {% if USE_SKINNYDIP|int == 1 %}
        G1 E{SKINNYDIP_DISTANCE} F{DIP_INSERTION_SPEED|float * 60}
        G4 P{MELT_ZONE_PAUSE}
        G1 E-{SKINNYDIP_DISTANCE} F{DIP_EXTRACTION_SPEED|float * 60}
        G4 P{COOLING_ZONE_PAUSE}
    {% endif %}

    {% if TOOLCHANGE_TEMP|float > 0 %}
        M104 S{OLD_TEMP}
    {% endif %}
    
    # Eject once all shaping is done - Testing only
    {% if FINAL_EJECT|int == 1 %}
        G92 E0
        G1 E-80 F{EXTRUDER_EJECT_SPEED|float * 60}
    # Park filament at fixed location
    {% elif PARKING_DISTANCE|int > 0 %}
        G90
        M82
        G1 E-{PARKING_DISTANCE} F{EXTRUDER_EJECT_SPEED|float * 60}
    {% endif %}

    RESTORE_GCODE_STATE NAME=MMU_FORM_TIP_state

